#include "Service.h"
//#include <signal.h>
#include <iostream>

using namespace std;
Service::Service()
{
}

void Service::Main()
{
	if(Init())
	{
		while(1)
		{
			CallBack();
		}
	}
}
bool Service::Init()
{
	/*
	struct sigaction sa;
	sa.sa_handler = SIG_IGN;
	sigaction(SIGPIPE, &sa, 0);
	*/
	return true;
}

NetService::NetService()
{
	epoll_handle = 0;
	socket = 0;
}

bool NetService::Init()
{
	if(!Service::Init())	return false;

	epoll_handle = epoll_create(10);
	if(epoll_handle == -1)	return false;

	socket = ::socket(AF_INET, SOCK_STREAM, 0);
	if(socket == -1)	return false;

	struct sockaddr_in adds;
	bzero(&adds, sizeof(adds));
	adds.sin_family = AF_INET;
	adds.sin_addr.s_addr = htonl(INADDR_ANY);
	adds.sin_port = htons(8888);

	//set socket for reuse
	int reuse = 1;
	if(::setsockopt(socket, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) == -1)
	{
		return false;
	}

	//set socket recv buf size
	socklen_t size = 128 * 1024;
	if(::setsockopt(socket, SOL_SOCKET, SO_RCVBUF, &size, sizeof(size)) == -1)
	{
		::close(socket);
		return false;
	}

	if(::setsockopt(socket, SOL_SOCKET, SO_SNDBUF, &size, sizeof(size)) == -1)
	{
		::close(socket);
		return false;
	}

	if(::bind(socket, (struct sockaddr*)&adds, sizeof(adds)) == -1)
	{
		::close(socket);
		return false;
	}

	if(::listen(socket, 100) == -1)
	{
		::close(socket);
		return false;
	}

	struct epoll_event ev;
	ev.events = EPOLLIN;
	ev.data.ptr = 0;
	if(::epoll_ctl(epoll_handle, EPOLL_CTL_ADD, socket, &ev))
	{
		::close(socket);
		return false;
	}

	return true;
}

void NetService::CallBack()
{
	struct epoll_event ev;
	bzero(&ev, sizeof(ev));

	int retcode = epoll_wait(epoll_handle, &ev, 1, 20);
	if(retcode==1 && (ev.events & EPOLLIN))
	{
		int socket_c = 0;
		struct sockaddr_in addr_c;
		socklen_t len= sizeof(addr_c);

		socket_c = ::accept(socket, (struct sockaddr*)&addr_c, &len);
		if(socket_c >= 0)
		{
			//add for process;
			Processor::getMe().AddClient(addr_c, socket_c);
		}
	}
}

Processor::Processor()
{
	clients.clear();
}

bool Processor::run()
{
	handle = epoll_create(20);
	while(1)
	{
		Loop();
	}

	return true;
}

void Processor::Loop()
{
	for(ClientContIter it = clients.begin(); it != clients.end(); ++it)
	{
		if(it->socket_handle == 0)
		{
			it->socket_handle = handle;
			struct epoll_event ev;
			ev.events = EPOLLIN | EPOLLERR | EPOLLPRI;
			ev.data.ptr = &(*it);
			if(::epoll_ctl(it->socket_handle, EPOLL_CTL_ADD, it->socket, &ev) == -1)
			{
				cout << "Register event failure" << endl;
				continue;
			}
		}

		struct epoll_event ev;
		int retcode = epoll_wait(handle, &ev, 10, 0);
		if(retcode > 0 && (ev.events & EPOLLIN))
		{
			char buf[20] = {0};
			int bytes = 0;
			bytes = ::recv(it->socket, buf, 19, MSG_DONTWAIT);
			if(bytes)
				cout << buf << endl;
		}
	}
}

void Processor::AddClient(struct sockaddr_in& addr, int socket)
{
	ClientInfo client;
	client.addr = addr;
	client.socket = socket;

	clients.push_back(client);
}
